function requestData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // resolve(222);
      reject(1111);
    }, 2000);
  });
}

function requestData1() {
  return Promise.reject(new Promise(() => {}));
}

async function foo() {
  const res = await {
    then: function (resolve, reject) {
      resolve("abc");
    },
  };
  console.log("res:", res);
  try {
    const res1 = await requestData();
    console.log("res1:", res1);
  } catch (error) {
    console.log("foo tryCatch", error); // 1111
  }
  // const res2 = await requestData();
  // console.log("res2:", res2);
}

// 如果await后面的表达式，返回的Promise是reject的状态，那么会将这个reject结果直接作为该async函数的Promise的reject值；
// 相当于内部返回了 Promise.reject(reject结果) 所以，需要 async函数的Promise进行catch操作，捕获Promise的reject值
// 或者使用 try catch 在 async函数内 将await 及后面的表达式 包裹起来， 用于捕获这个错误
// try catch 无法捕获异步promise内的抛出异常。但是await 相当于将后面的表达式推平成同步的
// （就是等后面的表达式执行完之后，再执行 Try catch操作）
// 所以 try catch 能捕获到 await 执行体 内 抛出的 promise 的 reject
// foo().catch((err) => {
//   console.log("err:", err);
// });

// UnhandledPromiseRejectionWarning: 1111
// 无法用 try catch 捕获错误
// try catch 无法捕获异步promise内的抛出异常
// 只能用 promise的catch 方法捕获这个 promise的reject值
// try {
//   foo();
// } catch (error) {
//   console.log("outside try:", error);
// }

// await表达式会暂停整个async函数的执行进程并出让其控制权，
// 只有当其等待的基于promise的异步操作被兑现或被拒绝之后才会恢复进程。
// promise的解决值会被当作该await表达式的返回值。
// 使用async / await关键字就可以在异步代码中使用普通的try / catch代码块。
async function foo2() {
  try {
    const res1 = await requestData1();
    console.log("res1:", res1);
  } catch (error) {
    console.log("foo tryCatch", error); // 1111
  }

  try {
    const res2 = await Promise.reject(new Promise(() => {}));
  } catch (error) {
    console.log("foo2Res2:", error);
  }

  // 如果一个promise没有被await修饰（没有被生成器的yield处理)，且最终状态为reject，没有被捕，并不会成为async函数的返回值
  // try catch 无法捕获异步promise内的抛出异常
  try {
    const res3 = Promise.reject("1111");
  } catch (error) {
    console.log(error);
  }
}
// 如果await修饰的promise最终是reject状态且没有被捕获，
// async会捕获并返回Promise.reject(error)，如果await修饰的promise是fullfill状态则async会return Promise.resolve()
// try catch 无法捕获异步promise内的抛出异常
foo2().catch((err) => {
  console.log("err:", err);
});
